using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmartLink.Domain.Entity;
using SmartLink.IRepository;
using SmartLink.Repository.Base;
using Dapper;
using SmartLink.Domain.ExpandEntity.Oragnization;
using SmartLink.EnumLibrary;
using SmartLink.Domain.ExpandEntity;
using SmartLink.Code;

namespace SmartLink.Repository
{
    public class BIZ_OrganizationRepo : RepositoryBase<BIZ_Organization>, IBIZ_OrganizationRepo
    {
        public bool CheckExistByOrgName(string orgName)
        {
            var sql = "SELECT EXISTS(SELECT * FROM BIZ_Organization WHERE IsDel=0 AND (OrganizationName=@OrgName OR OrganizationShorterName=@OrgName))";
            using (var conn = CreateConn())
            {
                return conn.ExecuteScalar<bool>(sql, new { OrgName = orgName });
            }
        }

        public IList<OrganizationManageExpand> GetOrganizationList(int status, int district, string keyValue, int pageIndex, int pageSize, bool isSearchTotal, out int count)
        {
            count = 0;
            var strDistrict = new StringBuilder();
            var result = new List<OrganizationManageExpand>();
            pageIndex = (pageIndex - 1) * pageSize;
            for (var i = 0; i < (10 - district.ToString().Length); i++)
            {
                strDistrict.Append("0");
            }
            strDistrict.Append(district);
            var param =
                new
                {
                    Status = status,
                    District = $"%{strDistrict}%",
                    KeyValue = $"%{keyValue}%",
                    PageIndex = pageIndex,
                    PageSize = pageSize
                };
            var selectSql = new StringBuilder($@"SELECT bo.ID,bo.OrganizationName,bo.OrganizationShorterName,bo.OrganizationType,sa.locationName OrganizationDistrict,count(bod.ID) StoreInfo,
                                                bo.OrganizationStatus,bo.Contact,bo.ContactPhone,bo.CreateTime,su.AccountName Creator, bo.ID AS OID
                                                FROM BIZ_Organization bo
                                                LEFT JOIN sys_area sa on sa.id=bo.Organizationdistrict
                                                LEFT JOIN biz_organizationdepartment bod ON bod.OID=bo.ID AND bod.Sign={OrganizationDepartmentSignEnum.门店.GetHashCode()}
                                                LEFT JOIN sys_user su ON su.ID=bo.Creator");
            var whereSql = new StringBuilder($@" where 1=1 and bo.Isdel={IsDelEnum.未删除.GetHashCode()}");
            if (status > -1)
            {
                whereSql.Append(" and bo.OrganizationStatus=@Status");
            }
            if (district > -1)
            {
                whereSql.Append(" and sa.location like @District");
            }
            if (!string.IsNullOrEmpty(keyValue))
            {
                whereSql.Append(" and (bo.ID like @KeyValue or bo.OrganizationName like @KeyValue)");
            }

            var groupbySql = " Group by bo.ID ";

            var dataFilter = new DataAuthorizeFilter(ModuleCodeEnum.OrganizationManage);
            var mainSql = dataFilter.WrapSql(selectSql.Append(whereSql).Append(groupbySql).ToString());

            var orderBySql = " order by CreateTime desc ";
            var limitSql = " limit @PageIndex,@PageSize";
            using (var conn = DapperHelper.GetDefaultConnection())
            {
                if (isSearchTotal)
                {
                    var countSql = new StringBuilder(@"select count(*) from (");
                    countSql.Append(mainSql);
                    countSql.Append(")a");
                    count = conn.ExecuteScalar<int>(countSql.ToString(), param);
                }
                result = conn.Query<OrganizationManageExpand>(mainSql + orderBySql + limitSql, param).ToList();
                conn.Close();
                return result;
            }
        }
        /// <summary>
        /// 组织机构列表(不分页)
        /// </summary>
        /// <returns></returns>
        public IList<BIZ_Organization> OrganizationListinfo()
        {
            List<BIZ_Organization> result;
            using (var conn = DapperHelper.GetDefaultConnection())
            {
                var sql = string.Format($"select  ID,OrganizationShorterName OrganizationName from biz_organization WHERE isdel={IsDelEnum.未删除.GetHashCode()} and organizationstatus=1");
                result = conn.Query<BIZ_Organization>(sql).ToList();
                conn.Close();
            }
            return result;
        }
        public SingleOragnizationInfoExapnd GetSingleOrganization(int orgId)
        {
            SingleOragnizationInfoExapnd result;
            using (var conn = DapperHelper.GetDefaultConnection())
            {
                var sql = string.Format(@"select bo.*,boparent.OrganizationShorterName OrganizationParentName,sa.locationName DistrictName,su.NickName CreatorName from BIZ_Organization bo
                                            left join sys_area sa on bo.OrganizationDistrict=sa.id
                                            LEFT JOIN biz_organization boparent on bo.ParentID=boparent.ID 
											left join sys_user su on su.ID=bo.Creator 
                                            where bo.isDel={0} and bo.id={1}", IsDelEnum.未删除.GetHashCode(), orgId);
                result = conn.QueryFirstOrDefault<SingleOragnizationInfoExapnd>(sql);
                conn.Close();
            }
            return result;
        }

        public static IEnumerable<int> GetDisabledCompanyIds()
        {
            using (var conn = DapperHelper.GetDefaultConnection())
            {
                var sql = string.Format($" select id from BIZ_Organization where isDel={IsDelEnum.未删除.GetHashCode()} and OrganizationStatus=0");
                return conn.Query<int>(sql);
            }
        }

        public IEnumerable<int> GetRootOrgDescendantsIds(int roid)
        {
            return GetDescendants(roid, true).OrderBy(a => a.ID).Select(a => a.ID);
        }

        #region 树查询

        /// <summary>
        /// 组织机构表树结构关系表
        /// </summary>
        private IEnumerable<SelfRelationRow> _selfTreeStructure
        {
            get
            {
                return base.SelfTreeStructure(DapperHelper.GetTableName(typeof(BIZ_Organization)));
            }
        }
        private IEnumerable<BIZ_Organization> GetOrganizations(string idConcatStr)
        {
            var sql = "SELECT * FROM BIZ_Organization WHERE FIND_IN_SET(ID, @IdStr) AND IsDel=0";
            if (!string.IsNullOrEmpty(idConcatStr))
            {
                using (var conn = CreateConn())
                {
                    return conn.Query<BIZ_Organization>(sql, new { IdStr = idConcatStr });
                }
            }
            return null;
        }
        /// <summary>
        /// 获取祖先节点集合
        /// </summary>
        /// <param name="topOid"></param>
        /// <returns></returns>
        public IEnumerable<BIZ_Organization> GetAncestors(int topOid, bool withSelf = false)
        {
            var ancestorsPath = _selfTreeStructure.Where(a => a.ID == topOid).Select(a => a.Path).SingleOrDefault();
            if (withSelf)
                ancestorsPath = string.Join(",", ancestorsPath, topOid);
            return GetOrganizations(ancestorsPath);
        }
        /// <summary>
        /// 获取后代节点结婚
        /// </summary>
        /// <param name="topOid"></param>
        /// <returns></returns>
        public IEnumerable<BIZ_Organization> GetDescendants(int topOid, bool withSelf = false)
        {
            var descendantsIds = _selfTreeStructure.Where(a => !string.IsNullOrEmpty(a.Path) && SelfRelationRow.ParsePath(a.Path).Contains(topOid)).Select(a => a.ID);
            var descendantsPath = string.Join(",", descendantsIds);
            if (withSelf)
                descendantsPath = string.Join(",", topOid, descendantsPath);
            return GetOrganizations(descendantsPath);
        }

        public IEnumerable<BIZ_Organization> GetRootOrganizations()
        {
            using (var conn = CreateConn())
            {
                return conn.Query<BIZ_Organization>("SELECT * FROM BIZ_Organization WHERE IsDel=0 AND ParentID IS NULL");
            }
        }

        public int GetRootOrganizationId(int oid)
        {
            var ancestorsPath = _selfTreeStructure.Where(a => a.ID == oid).Select(a => a.Path).SingleOrDefault();
            if (string.IsNullOrEmpty(ancestorsPath)) return oid;
            return Array.ConvertAll(ancestorsPath.Split(','), s => Convert.ToInt32(s)).First();
        }

        #endregion
    }
}
